/*
Module : CPL_PP.H
Purpose: Declaration for an MFC wrapper class for Control Panel Applets
Created: PJN / 18-07-1999

Copyright (c) 1999 - 2009 by PJ Naughter (Web: www.naughter.com, Email: pjna@naughter.com)

All rights reserved.

Copyright / Usage Details:

You are allowed to include the source code in any product (commercial, shareware, freeware or otherwise) 
when your product is released in binary form. You are allowed to modify the source code in any way you want 
except you cannot modify the copyright details at the top of each module. If you want to distribute source 
code with your application, then you are only allowed to distribute versions released by the author. This is 
to maintain a single distribution point for the source code. 

*/


///////////////////// Macros / Defines ////////////////////////////////////////

#pragma once

#ifndef __CPL_PP_H__
#define __CPL_PP_H__

#ifndef __AFXTEMPL_H__
#include <afxtempl.h> 
#pragma message("To avoid this message please put afxtempl.h in your PCH (normally stdafx.h)")
#endif

#define DECLARE_CPLAPP()\
	LONG WINAPI APIENTRY CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2);

#define DECLARE_CPLREGISTER()\
	STDAPI DllRegisterServer();\
	STDAPI DllUnregisterServer();

#define IMPLEMENT_CPLAPP()\
	LONG APIENTRY CPlApplet(HWND hwndCPl, UINT uMsg, LPARAM lParam1, LPARAM lParam2)\
	{\
		AFX_MANAGE_STATE(AfxGetStaticModuleState());\
		return GetControlPanelApp()->OnCplMsg( hwndCPl, uMsg, lParam1, lParam2 );\
	};\

#define IMPLEMENT_CPLREGISTER_FOR_ALL_USERS(pszAppPath, pszCategory, pszGUID, pszCanonicalName, pszTaskLinksFile, safeModeValue)\
	STDAPI DllRegisterServer()\
	{\
		AFX_MANAGE_STATE(AfxGetStaticModuleState() );\
		if (GetControlPanelApp()->RegisterApplet(pszAppPath, TRUE, TRUE, pszCategory, pszGUID, pszCanonicalName, pszTaskLinksFile, safeModeValue))\
			return S_OK;\
		else\
			return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());\
	};\
	STDAPI DllUnregisterServer()\
	{\
		AFX_MANAGE_STATE(AfxGetStaticModuleState());\
		if (GetControlPanelApp()->RegisterApplet(pszAppPath, FALSE, TRUE, pszCategory, pszGUID, pszCanonicalName, pszTaskLinksFile, safeModeValue))\
			return S_OK;\
		else\
			return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());\
	};

#define IMPLEMENT_CPLREGISTER_FOR_CURRENT_USER(pszAppPath, pszCategory, pszGUID, pszCanonicalName, pszTaskLinksFile, safeModeValue)\
	STDAPI DllRegisterServer()\
	{\
		AFX_MANAGE_STATE(AfxGetStaticModuleState() );\
		if (GetControlPanelApp()->RegisterApplet(pszAppPath, TRUE, FALSE, pszCategory, pszGUID, pszCanonicalName, pszTaskLinksFile, safeModeValue))\
			return S_OK;\
		else\
			return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());\
	};\
	STDAPI DllUnregisterServer()\
	{\
		AFX_MANAGE_STATE(AfxGetStaticModuleState());\
		if (GetControlPanelApp()->RegisterApplet(pszAppPath, FALSE, FALSE, pszCategory, pszGUID, pszCanonicalName, pszTaskLinksFile, safeModeValue))\
			return S_OK;\
		else\
			return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());\
	};


//////////////////// Classes //////////////////////////////////////////////////

//Class which encapsulates one control panel applet
class CControlPanelApplet : public CCmdTarget
{
public:
//Constructors / Destructors
  CControlPanelApplet(UINT nResourceID, CRuntimeClass* pUIClass);
  CControlPanelApplet(UINT nResourceID, UINT nDescriptionID, CRuntimeClass* pUIClass);

protected:
//Overridable Member Functions
  virtual LONG OnRun(CWnd* pParentWnd);
  virtual LONG OnStartParms(CWnd* pParentWnd, LPCTSTR lpszExtra);
  virtual LONG OnInquire(CPLINFO* pInfo);
  virtual LONG OnNewInquire(NEWCPLINFO* pInfo);
  virtual LONG OnSelect();
  virtual LONG OnStop();

//Data members
  CRuntimeClass* m_pUIClass;       //Pointer to property sheet or dialog to display
  BOOL           m_bDynamic;       //Show this class respond to OnNewInquire instead of OnInquire
  UINT           m_nResourceID;    //Resource ID of the string resource for this applet
  UINT           m_nDescriptionID; //Resource ID of the description to use (only used for CPL_INQUIRE)
  CString        m_sName;          //The name of the control panel applet
  int            m_nPageNumber;    //The initial page to display
  
  friend class CControlPanelApp;   //The app class is allowed to access our innards

  DECLARE_DYNAMIC(CControlPanelApplet);
};

//The main app class which contains all the applets in this dll
class CControlPanelApp : public CWinApp
{
public:
//Enums
  enum SafeModeValue
  {
    NotSpecified = 0,
    MinimalSafeModeOnly = 1,
    SafeModeIfNetworkingEnabled = 2,
    AnyFormOfSafeMode = 3
  };

//Constructors / Destructors
  CControlPanelApp();
  virtual ~CControlPanelApp();

//Public Methods
  void AddApplet(CControlPanelApplet* pApplet);
  virtual LONG OnCplMsg(HWND hWndCPl, UINT msg, LPARAM lp1, LPARAM lp2);
  BOOL RegisterApplet(LPCTSTR pszAppPath, BOOL bRegister, BOOL bForAllUsers, LPCTSTR pszCategory, LPCTSTR pszGUID, LPCTSTR pszCanonicalName, LPCTSTR pszTaskLinksFile, SafeModeValue safeModeValue);
  
//Static Methods  
  static BOOL RegisterApplet(LPCTSTR pszAppPath, LPCTSTR pszAppName, BOOL bRegister, BOOL bForAllUsers, LPCTSTR pszCategory, LPCTSTR pszGUID, LPCTSTR pszCanonicalName, LPCTSTR pszTaskLinksFile, SafeModeValue safeModeValue);
  static BOOL RegisterAppletViaIniFile(BOOL bRegister, LPCTSTR pszAppName, LPCTSTR pszAppPath);
  static BOOL RegisterAppletViaRegistry(BOOL bRegister, BOOL bForAllUsers, LPCTSTR pszAppName, LPCTSTR pszAppPath);
  static BOOL RegisterXPCategory(BOOL bRegister, BOOL bForAllUsers, DWORD dwCategoryID, LPCTSTR pszAppPath);
  static BOOL RegisterXPCategories(BOOL bRegister, BOOL bForAllUsers, LPCTSTR pszCategories, LPCTSTR pszAppPath);
  static BOOL RegisterVistaCategory(BOOL bRegister, BOOL bForAllUsers, DWORD dwCategoryID, LPCTSTR pszAppPath);
  static BOOL RegisterVistaCategories(BOOL bRegister, BOOL bForAllUsers, LPCTSTR pszCategories, LPCTSTR pszAppPath);
  static BOOL RegisterGUID(BOOL bRegister, BOOL bForAllUsers, LPCTSTR pszAppPath, LPCTSTR pszGUID);
  static BOOL RegisterCanonicalName(BOOL bRegister, BOOL bForAllUsers, LPCTSTR pszCanonicalName, LPCTSTR pszAppPath);
  static BOOL RegisterTaskLinks(BOOL bRegister, BOOL bForAllUsers, LPCTSTR pszTaskLinksFile, LPCTSTR pszAppPath);
  static BOOL RegisterSafeMode(BOOL bRegister, BOOL bForAllUsers, DWORD dwValue, LPCTSTR pszAppPath);
  static CString DoReplaceableStringParameters(const CString& sPath);

protected:
//Member variables
  CList<CControlPanelApplet*, CControlPanelApplet*&> m_Applets; //The array of all the control panel applets

//Methods
  virtual LONG OnInit();
  virtual LONG OnExit();

  DECLARE_DYNAMIC(CControlPanelApp);
};

//Global Functions
CControlPanelApp* GetControlPanelApp();

#endif //__CPL_PP_H__
